package com.jgz.websocketdemo;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.jgz.websocketdemo.type.ArenaGameTypeEnum;
import com.jgz.websocketdemo.type.ArenaMsgTypeEnum;
import com.jgz.websocketdemo.type.ArenaTypeEnum;
import com.jgz.websocketdemo.type.ContestantInfo;
import com.jgz.websocketdemo.type.ItBrainHoleQuestion;
import com.jgz.websocketdemo.type.QuestionOptionEnum;
import com.jgz.websocketdemo.type.WebSocketInfo;
import com.jgz.websocketdemo.type.WebSocketMsgParam;
import com.jgz.websocketdemo.type.WebSocketMsgResult;

import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.WebSocket;
import okhttp3.WebSocketListener;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btnStart;
    private Button btnSend;
    private Button btnSub;
    private Button btnCom;
    private TextView tvOutput;
    private TextView mPersonalCount;
    private TextView mQuestionTv;
    private TextView mScore;
    private TextView mRoomNo;
    private Button mATv;
    private Button mBTv;
    private Button mCTv;
    private Button mDTv;
    private WebSocket mSocket;
    private String roomNo = "";

    private String token = "auth " + "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJhcHAtaXQtYnJhaW4taG9sZCIsImlhdCI6MTU0NTExNTUzNywiYXVkIjoiMTg4MTExMTIyMjIiLCJzdWIiOiJ7XCJhdXRob3JpemF0aW9uc1wiOltcIlJPTEVfVVNFUlwiXX0ifQ.TNSjhkNNYj4fG0xCCWe2qiZ1L0AxVN6oKwar_ZfwhSHVDx3Vh_lpa0_W2LpYryMn2gT7WLRmT2iS0dZyx45Khw";
    //private String token = "auth " + "eyJhbGciOiJIUzUxMiJ9.eyJpc3MiOiJhcHAtaXQtYnJhaW4taG9sZCIsImlhdCI6MTU0NTE5OTE1NywiYXVkIjoiMTg4MjIyMjMzMzMiLCJzdWIiOiJ7XCJhdXRob3JpemF0aW9uc1wiOltcIlJPTEVfVVNFUlwiXX0ifQ.XH7Fvs6yqjyZi1C3GX0F5Ex8_00h8aSaJVGocWQ5QTZrS-3-_HpkJziGVQ9wDNku3dGLmxbx0IK7yBvudyEQ6A";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btnStart = findViewById(R.id.start);
        btnSend = findViewById(R.id.send);
        btnSub = findViewById(R.id.subscribe);
        btnCom = findViewById(R.id.commit);
        tvOutput = findViewById(R.id.output);
        mPersonalCount = findViewById(R.id.tv_personalCount);
        mQuestionTv = findViewById(R.id.tv_question);
        mATv = findViewById(R.id.tv_A);
        mBTv = findViewById(R.id.tv_B);
        mCTv = findViewById(R.id.tv_C);
        mDTv = findViewById(R.id.tv_D);

        mScore = findViewById(R.id.score_tv);
        mRoomNo = findViewById(R.id.roomNo_tv);

        btnStart.setOnClickListener(this);
        btnSend.setOnClickListener(this);
        btnSub.setOnClickListener(this);
        btnCom.setOnClickListener(this);

        mATv.setOnClickListener(this);
        mBTv.setOnClickListener(this);
        mCTv.setOnClickListener(this);
        mDTv.setOnClickListener(this);
    }


    private void start() {
        if (mSocket == null) {
            OkHttpClient mOkHttpClient = new OkHttpClient.Builder()
                    .readTimeout(3, TimeUnit.SECONDS)//设置读取超时时间
                    .writeTimeout(3, TimeUnit.SECONDS)//设置写的超时时间
                    .connectTimeout(3, TimeUnit.SECONDS)//设置连接超时时间
                    .build();

            Request request = new Request.Builder().url("ws://192.168.1.174:11111").header("Authorization", token).build();
            EchoWebSocketListener socketListener = new EchoWebSocketListener();
            mOkHttpClient.newWebSocket(request, socketListener);
            mOkHttpClient.dispatcher().executorService().shutdown();
        } else {
            mSocket.cancel();
        }

    }


    private final class EchoWebSocketListener extends WebSocketListener {

        @Override
        public void onOpen(WebSocket webSocket, Response response) {
            super.onOpen(webSocket, response);
            mSocket = webSocket;
        }

        @Override
        public void onMessage(WebSocket webSocket, String text) {
            super.onMessage(webSocket, text);

            WebSocketMsgResult msgResult = new Gson().fromJson(text, WebSocketMsgResult.class);
            if (msgResult.getArenaMsgType() == ArenaMsgTypeEnum.ARENA_USER_COUNT) {
                final WebSocketMsgResult<WebSocketInfo> infoWebSocketMsgResult = new Gson().fromJson(text, new TypeToken<WebSocketMsgResult<WebSocketInfo>>() {
                }.getType());
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mPersonalCount.setText(String.valueOf(infoWebSocketMsgResult.getData().getConnSize()));
                    }
                });

                return;
            }

            if (msgResult.getArenaMsgType() == ArenaMsgTypeEnum.MATCHING_SUCCESS && msgResult.getTopic() != null) {
                WebSocketMsgResult<ContestantInfo> result = new Gson().fromJson(text, new TypeToken<WebSocketMsgResult<ContestantInfo>>() {
                }.getType());
                output("");
                WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
                webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.SUB_THEME);
                webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
                webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
                webSocketMsgParam.setTopic(result.getTopic());
                roomNo = result.getTopic();
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mRoomNo.setText(roomNo);
                    }
                });
                String content = new Gson().toJson(webSocketMsgParam);
                output(content);
                if (!TextUtils.isEmpty(content) && mSocket != null) {
                    mSocket.send(content);
                }
                return;
            }

            if (msgResult.getArenaMsgType() == ArenaMsgTypeEnum.QUESTION) {
                final WebSocketMsgResult<ItBrainHoleQuestion> result = new Gson().fromJson(text, new TypeToken<WebSocketMsgResult<ItBrainHoleQuestion>>() {
                }.getType());

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mQuestionTv.setText("题目:" + result.getData().getQuestion());
                        mATv.setText(result.getData().getOptionA());
                        mBTv.setText(result.getData().getOptionB());
                        mCTv.setText(result.getData().getOptionC());
                        mDTv.setText(result.getData().getOptionD());
                    }
                });
                return;
            }

            if (msgResult.getArenaMsgType() == ArenaMsgTypeEnum.UPDATE_SCORE) {
                final WebSocketMsgResult<CopyOnWriteArraySet<ContestantInfo>> result = new Gson().fromJson(text, new TypeToken<WebSocketMsgResult<CopyOnWriteArraySet<ContestantInfo>>>() {
                }.getType());

                CopyOnWriteArraySet<ContestantInfo> data = result.getData();
                for (final ContestantInfo contestantInfo : data) {
                    if (contestantInfo.getNickname().equals("**2222")) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                mScore.setText(contestantInfo.getCurrentIntegration() + "");
                            }
                        });
                        break;
                    }
                }
            }

        }

        @Override
        public void onClosed(WebSocket webSocket, int code, String reason) {
            super.onClosed(webSocket, code, reason);
            output("closed:" + reason);
            mSocket = null;
        }

        @Override
        public void onClosing(WebSocket webSocket, int code, String reason) {
            super.onClosing(webSocket, code, reason);
            output("closing:" + reason);
            mSocket = null;
        }

        @Override
        public void onFailure(WebSocket webSocket, Throwable t, Response response) {
            super.onFailure(webSocket, t, response);
            output("failure:" + t.getMessage());
            mSocket = null;
        }
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.start://开始连接
                start();
                break;
            case R.id.send:
                send();
                break;
            case R.id.subscribe:
                sub();
                break;
            case R.id.commit:
                commit();
                break;
            case R.id.tv_A:
                commitA();
                break;
            case R.id.tv_B:
                commitB();
                break;
            case R.id.tv_C:
                commitC();
                break;
            case R.id.tv_D:
                commitD();
                break;
            default:
                break;
        }
    }

    private void sub() {
    }

    private void send() {
        //  String content = etContent.getText().toString().trim();
        WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
        webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.START_GAME);
        webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
        webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
        String content = new Gson().toJson(webSocketMsgParam);
        System.out.println(content);
        if (!TextUtils.isEmpty(content) && mSocket != null) {
            mSocket.send(content);
        }
    }

    private void commit() {
        //  String content = etContent.getText().toString().trim();
        WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
        webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.COMMIT);
        webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
        webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
        webSocketMsgParam.setOption(QuestionOptionEnum.A);
        webSocketMsgParam.setTopic(roomNo);
        String content = new Gson().toJson(webSocketMsgParam);
        System.out.println(content);
        if (!TextUtils.isEmpty(content) && mSocket != null) {
            mSocket.send(content);
        }
    }

    private void commitA() {
        //  String content = etContent.getText().toString().trim();
        WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
        webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.COMMIT);
        webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
        webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
        webSocketMsgParam.setOption(QuestionOptionEnum.A);
        webSocketMsgParam.setTopic(roomNo);
        String content = new Gson().toJson(webSocketMsgParam);
        System.out.println(content);
        if (!TextUtils.isEmpty(content) && mSocket != null) {
            mSocket.send(content);
        }
    }

    private void commitB() {
        //  String content = etContent.getText().toString().trim();
        WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
        webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.COMMIT);
        webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
        webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
        webSocketMsgParam.setOption(QuestionOptionEnum.B);
        webSocketMsgParam.setTopic(roomNo);
        String content = new Gson().toJson(webSocketMsgParam);
        System.out.println(content);
        if (!TextUtils.isEmpty(content) && mSocket != null) {
            mSocket.send(content);
        }
    }

    private void commitC() {
        //  String content = etContent.getText().toString().trim();
        WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
        webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.COMMIT);
        webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
        webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
        webSocketMsgParam.setOption(QuestionOptionEnum.C);
        webSocketMsgParam.setTopic(roomNo);
        String content = new Gson().toJson(webSocketMsgParam);
        System.out.println(content);
        if (!TextUtils.isEmpty(content) && mSocket != null) {
            mSocket.send(content);
        }
    }

    private void commitD() {
        //  String content = etContent.getText().toString().trim();
        WebSocketMsgParam webSocketMsgParam = new WebSocketMsgParam();
        webSocketMsgParam.setMsgType(ArenaMsgTypeEnum.COMMIT);
        webSocketMsgParam.setGameType(ArenaGameTypeEnum.JAVA);
        webSocketMsgParam.setArenaType(ArenaTypeEnum.SINGLE);
        webSocketMsgParam.setOption(QuestionOptionEnum.D);
        webSocketMsgParam.setTopic(roomNo);
        String content = new Gson().toJson(webSocketMsgParam);
        System.out.println(content);
        if (!TextUtils.isEmpty(content) && mSocket != null) {
            mSocket.send(content);
        }
    }


    private void output(final String text) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                tvOutput.setText(tvOutput.getText().toString() + "\n\n" + text);
            }
        });
    }

}
